#****************************************************************************
#File Name   : Base.py
#Description : This file defines the base class of the ACP message
#              CItem -- This is the basic class, every element is derived
#                       from this class, it contains display information
#              InfoElement -- The base element of ACP message
#                             It's also derived from CItem,                               
#****************************************************************************
import re

SUB_INDENT = '    '
DATA_STRING_FORMAT = "0x{0:s}"
STRING_FORMAT = "{0:s}"
HEX_DATA_FORMAT = "0x{0:02X}"
DATA_FORMAT = "{0:d}"
SUB_INDENT = '    '
WIDETH = 32

HI_GROUP_NAME_PREFIX="acpMsg"

#control fucntion
CONTROL_FUNCTION_NONE=0
CONTROL_FUNCTION_SVT=1
CONTROL_FUNCTION_GEO=4
CONTROL_FUNCTION_SPD=6
CONTROL_FUNCTION_RDC=11
CONTROL_FUNCTION_MAN=15
CONTROL_FUNCTION_MIL=16
CONTROL_FUNCTION_ALM=17

class CItem(object):
    def __init__(self, name):
        self._name = name
        #raw data of the message string in the log
        #it's displayed in HEX format
        self._rawStr = ''
        #display the additional information
        self._infoStr = ''
        #display error information
        self._errStr = ''

        #the item has sub item
        #for example, message consist of element,
        #here message is item, element is subitem
        #use a dict to implement this list, the format is 
        #  itemName : item
        #so we can use the item name to find item
        self._subList = {}
        #as dict is not sorted, we use a name list to sort the item
        self._nameList = []

        self._indent = ''
        self._sepPos = WIDETH #The position where put seperator

        #syntax group name
        self._synGrpName = HI_GROUP_NAME_PREFIX + re.sub(' ','',name)

        self._highLighter = 0

        self._hlColor = 'Normal'

    def GetName(self):
        return self._name

    def AddSubItem(self, item):
        name = item.GetName()
        self._subList[name] = item
        self._nameList.append(name)

    def CreateSubItem(self, name):
        item = CItem(name)
        self._subList[name] = item
        self._nameList.append(name)
        return item

    def SetIndent(self, indent):
        self._indent = indent
    def GetIndent(self):
        return self._indent
    def SetSepPos(self, pos):
        self._sepPos = pos
    def GetSepPos(self):
        return self._sepPos

    def FindSub(self, name):
        return self._subList[name]

    def SetHighLighter(self, highLighter):
        self._highLighter = highLighter

    def SetColor(self, color):
        self._hlColor = color

    def SetSyntaxGroup(self):
        hl = self._highLighter
        if hl != 0:
            pattern = re.sub('0x','',self._rawStr)
            hl.SetSynGroup(self._synGrpName, pattern)
            hl.SetHlColor(self._synGrpName, self._hlColor)

        for name,subItem in self._subList.items():
            subItem.SetSyntaxGroup()

    def FormDisplayString(self):
        if self._errStr != '' :
            self._errStr = "----Error:" + "(" + self._errStr + ")"

        if self._infoStr != '':
            self._infoStr = "(" + self._infoStr + ")"

        #display item information
        str = self._indent + ("{name:<"+"%d"%self._sepPos+"} : {raw} {info} {error}").format(name=self._name, raw=self._rawStr, info=self._infoStr, error=self._errStr)

        str = str + "\n"

        #display sub item information
        for name in self._nameList:
            if name in self._subList:
                subItem = self._subList[name]
                subItem.SetIndent(self.GetIndent() + SUB_INDENT)
                subItem.SetSepPos(self.GetSepPos() - len(SUB_INDENT))
                str = str + subItem.FormDisplayString()
            else:
                str = "The item is wrong\n"


        return str

    #use this function to initialize sub item list
    def InitSubItem(self):
        pass

    def Parse(self, dataStr):
        pass

class CInfoElement(CItem):
    '''information element:
       This is the base class of message element'''
    _gName = "Information Element"
    _gNameHeader = "Header"

    def __init__(self,name=_gName):
        super(CInfoElement, self).__init__(name)

    def FormDisplayString(self):
        str = '\n'

        str = str + super(CInfoElement, self).FormDisplayString()

        return str

    def InitSubItem(self):
        name = self._gNameHeader
        item = CEleHeader(name)
        self._subList[name] = item
        self._nameList.append(name)

    def CreateHeader(self, name):
        item = CEleHeader(name)
        self._subList[name] = item
        self._nameList.append(name)

    def ParseElement(self, dataStr):
        pass

    def Parse(self, dataStr):
        #first initialize the sub item list
        self.InitSubItem()

        self._startIndex = dataStr.GetIndex()
        header = self._subList[self._gNameHeader]
        header.Parse(dataStr)

        self.ParseElement(dataStr)

        #the raw data should include whole element string
        hLen=header.GetHeaderLength()
        len=header.GetLength()
        self._rawStr = DATA_STRING_FORMAT.format(dataStr.GetString(self._startIndex, self._startIndex + hLen + len))




        #end of parse()

